home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
games
/
ippon
/
source.lzh
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-07-07
|
15KB
|
614 lines
/* 男は一本槍 */
/* main.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/dos.h>
#include <sys/iocs.h>
#include <XSP2lib.H>
#include <pcm8afnc.h>
#define GLOBAL_DEFINE /* グローバル変数を確保する */
#include "main.h"
#include "player.h"
#include "shot.h"
#include "enemy.h"
#include "eshot.h"
#include "effect.h"
#include "entry.h"
#include "psearch.h"
#include "gvram.h"
#include "txfont.h"
#include "sound.h"
static int old_crtmod;
#define PCG_MAX 322 /* パターンデータの個数 */
#define REF_MAX 564 /* リファレンスデータの個数 */
#define FRM_MAX 10588 /* フレームデータの個数 */
static char pcg_alt[PCG_MAX + 1]; /* PCG配置管理テーブル */
static char pcg_dat[PCG_MAX * 128]; /* PCGデータファイル読み込みバッファ */
static XOBJ_REF_DAT ref_dat[REF_MAX]; /* リファレンスデータ */
static XOBJ_FRM_DAT frm_dat[FRM_MAX]; /* フレームデータ */
static int sizeof_pcg = 0; /* スプライトPCGパターン読み込み数 */
static int sizeof_ref = 0; /* 複合スプライトリファレンスデータ読み込み数 */
static int sizeof_frm = 0; /* 複合スプライトフレームデータ読み込み数 */
static int high_score = 68000;
static unsigned short pal_dat[16][15]; /* スプライトパレットデータ */
static unsigned short title_pal_dat[16][15]; /* タイトルロゴのスプライトパレットデータ */
enum {
SELECT_START = 0, SELECT_EXIT,
};
#define RGB(r,g,b) ((g)<<11|(r)<<6|(b)<<1)
void usage (void)
{
printf (
"縦スクロールシューティング・一本槍 IPPON.X ver1.00"
" programmed by Mitsuky <FreeSoftware>\n"
);
}
/* ボタンが押されるか timer フレーム経つまで待つ */
static void WaitTime (int timer)
{
int t = timer;
while ((_iocs_joyget (0) & 0x60) != 0x60);
do {
xsp_vsync (1);
if ((_iocs_joyget (0) & 0x60) != 0x60)
break;
} while (t--);
while ((_iocs_joyget (0) & 0x60) != 0x60);
}
static void TextClear (void)
{
_iocs_txrascpy (256 / 4 * 256, 256 / 4, 0b1111); /* テキスト画面クリア */
}
/* 垂直同期ごとに呼ばれるルーチン */
static void VdispRoutine (void)
{
static int y0 = 0, y1 = 0;
if (pause_flag)
return; /* ポーズ中ならここまで */
*(volatile unsigned int *) 0xe80018 = *(volatile unsigned int *) 0xe8001c = y0;
y0 -= 2;
y0 &= 511;
*(volatile unsigned int *) 0xe80020 = *(volatile unsigned int *) 0xe80024 = y1;
y1 -= 4;
y0 &= 511;
}
/* 終了時に1度だけ呼ばれる・エラーだったら返ってこない */
void Tini (void)
{
int sp;
switch (error_level) {
case ERROR_NON:
xsp_vsyncint_off ();
pcm8a_vsyncint_off ();
xsp_off ();
/* 画面モードを元に戻す */
sp = _iocs_b_super (0);
*(unsigned short *) 0xe8e006 &= 0xfffd; /* HRL ビットを元に戻す */
_iocs_b_super (sp);
_iocs_crtmod (old_crtmod);
_iocs_g_clr_on (); /* 一応 */
_dos_kflushio (0xff); /* キーバッファをクリア */
/* break が無い事に注意 */
case ERROR_SOUND:
SoundTini ();
/* break が無い事に注意 */
case ERROR_FILE:
_iocs_tgusemd (1, 3);
/* break が無い事に注意 */
case ERROR_GUSEMD:
_iocs_tgusemd (0, 3);
/* break が無い事に注意 */
case ERROR_TUSEMD:
/* break が無い事に注意 */
default:
break;
}
_iocs_b_curon ();
if (error_level != ERROR_NON) {
/* エラーが発生した場合 */
puts (error_message);
exit (-1); /* 終了する */
}
}
/* 起動時のファイル読み込み */
/* 読み込みに失敗した場合はいきなり終了するので注意 */
/* 返り値 : 読み込んだ項目数 */
static int LoadFile (char *fname, void *ptr, size_t size, size_t n)
{
FILE *fp;
int i;
fp = fopen (fname, "rb");
if (fp == NULL) {
static char e[256];
error_level = ERROR_FILE;
error_message = e;
sprintf (e, "ファイル %s が読み込めません\n", fname);
Tini (); /* 返ってこない */
}
i = fread (ptr, size, n, fp);
fclose (fp);
return (i); /* 返り値は読み込み項目数 */
}
/* XSP 各種データ読み込み・ファイル名は拡張子を付けずに指定すること */
/* 返り値 : 複合スプライトNo. */
static short LoadXSP (char *fname)
{
int i;
int p, f, r;
short obj_no = sizeof_ref;
char temp_fname[92];
strcpy (temp_fname, fname);
strcat (temp_fname, ".FRM");
f = LoadFile (temp_fname, &frm_dat[sizeof_frm], sizeof (XOBJ_FRM_DAT), FRM_MAX - sizeof_frm);
strcpy (temp_fname, fname);
strcat (temp_fname, ".REF");
r = LoadFile (temp_fname, &ref_dat[sizeof_ref], sizeof (XOBJ_REF_DAT), REF_MAX - sizeof_ref);
strcpy (temp_fname, fname);
strcat (temp_fname, ".XSP");
p = LoadFile (temp_fname, &pcg_dat[sizeof_pcg], sizeof (char), 128 * PCG_MAX - sizeof_pcg);
/* FRM_DAT[].pt 補正 */
for (i = 0; i < f; i++)
frm_dat[sizeof_frm + i].pt += sizeof_pcg / 128;
/* REF_DAT[].ptr 補正 */
for (i = 0; i < r; i++)
(int) ref_dat[sizeof_ref + i].ptr += (int) (&frm_dat[sizeof_frm]);
sizeof_pcg += p;
sizeof_frm += f;
sizeof_ref += r;
#ifdef DEBUG
printf ("%s を読み込みました sizeof_ref = %hd\n", fname, obj_no);
#endif
return (obj_no);
}
/* SP データ読み込み */
static short LoadSP (char *fname)
{
int p;
short sp_no = sizeof_pcg / 128;
char temp_fname[92];
strcpy (temp_fname, fname);
strcat (temp_fname, ".SP");
p = LoadFile (temp_fname, &pcg_dat[sizeof_pcg], sizeof (char), 128 * PCG_MAX - sizeof_pcg);
sizeof_pcg += p;
#ifdef DEBUG
printf ("%s を読み込みました sp_no = %hd\n", fname, sp_no);
#endif
return (sp_no);
}
/* 起動時に1度だけ呼ばれる */
static void Init (void)
{
int sp;
int i;
static unsigned short crtcdata[9] =
{69, 6, 11 + 8, 59 - 8, 567, 5, 40, 552, 0x0111};
static unsigned short textpalet[16] =
{0, RGB (16, 16, 20), RGB (12, 12, 20), RGB (28, 28, 31), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned short *s, *d;
error_message = NULL;
/* テキスト画面の使用状況をチェック */
error_level = ERROR_TUSEMD;
if (_iocs_tgusemd (1, -1) == 2) { /* ユーザーが使用中なら */
error_message = "テキスト VRAM が使用中です";
Tini ();
}
_iocs_tgusemd (1, 2);
/* グラフィック画面の使用状況をチェック */
error_level = ERROR_GUSEMD;
i = _iocs_tgusemd (0, -1);
if ((i == 1) || (i == 2)) { /* システムまたはユーザーが使用中なら */
error_message = "グラフィック VRAM が使用中です";
Tini ();
}
_iocs_tgusemd (0, 2);
/* 各種ファイル読み込み */
error_level = ERROR_FILE;
obj_player = LoadXSP ("SP/PLAYER");
obj_shot = LoadXSP ("SP/SHOT");
obj_zako02 = LoadXSP ("SP/ZAKO02");
obj_covern = LoadXSP ("SP/COVERN");
obj_oplaser = LoadXSP ("SP/OPLASER");
obj_round4 = LoadXSP ("SP/ROUND4");
obj_coverf = LoadXSP ("SP/COVERF");
obj_sword = LoadXSP ("SP/SWORD");
obj_searchz = LoadXSP ("SP/SEARCHZ");
obj_zako03 = LoadXSP ("SP/ZAKO03");
obj_lboss01 = LoadXSP ("SP/LBOSS01");
obj_explall = LoadXSP ("SP/EXPLALL");
obj_points = LoadXSP ("SP/POINTS");
obj_title = LoadXSP ("SP/TITLE");
sp_core = LoadSP ("SP/CORE");
sp_eshot = LoadSP ("SP/ESHOT");
sp_eshotera = LoadSP ("SP/ESHOTERA");
#ifdef DEBUG
printf (" PCG 使用数 = %d\n REF 使用数 = %d\n FRM 使用数 = %d\n",
sizeof_pcg / 128, sizeof_ref, sizeof_frm);
#endif
LoadFile ("SP/MAIN.PAL", &pal_dat, sizeof (unsigned short), 16 * 15);
LoadFile ("SP/TITLE.PAL", &title_pal_dat, sizeof (unsigned short), 16 * 15);
LoadFile ("TBL/PSTABLE.DAT", pstable, sizeof (unsigned char), 256 * 256);
LoadFile ("TBL/RNDTABLE.DAT", rndtable, sizeof (unsigned char), 256);
LoadFile ("TBL/XYTABLE.DAT", &xytable, sizeof (VECTOR), SPEED_MAX * 256);
LoadFile ("DAT/STAGE.DAT", &stage_data, sizeof (ENTRY), ENTRY_MAX);
LoadFile ("DAT/ALPHA2.DAT", &font_data, sizeof (unsigned char), 2048);
LoadFile ("BG/STAGE.MAP", bg_map, sizeof (char), 30 + 32 * 128 * 2);
LoadFile ("BG/STAGE.SP", bg_sp, sizeof (char), 32 * 256);
LoadFile ("BG/STAGE.PAL", bg_pal, sizeof (unsigned short), 64);
error_level = ERROR_SOUND;
SoundInit ();
error_level = ERROR_NON; /* エラーなし */
/* XSP 関連の初期化 */
xsp_on ();
xsp_mode (3);
/* パターンデータを定義 */
xsp_pcgdat_set (pcg_dat, pcg_alt, sizeof (pcg_alt));
xsp_objdat_set (ref_dat);
/* 画面モードの初期化 */
/* 256x256ドット 31kHz 256色モードに */
old_crtmod = _iocs_crtmod (-1); /* 前の CRTMOD を保存 */
_iocs_crtmod (10); /* 256x256dot 31kHz 256色 */
_iocs_g_clr_on (); /* 一応 */
_iocs_sp_init (); /* スプライトの初期化 */
_iocs_sp_on ();
/* 256x256 正方形モードを作る */
sp = _iocs_b_super (0);
*(unsigned short *) 0xe80028 = crtcdata[8];
d = (unsigned short *) 0xe80002;
for (i = 1; i < 8; i++)
*d++ = crtcdata[i];
*(unsigned short *) 0xe80000 = crtcdata[0];
*(unsigned short *) 0xe8e006 |= 0b10; /* HRL ビット */
*(unsigned short *) 0xeb080c = crtcdata[2] + 4;
*(unsigned short *) 0xeb080a = crtcdata[0]; /* スプライト */
*(unsigned short *) 0xeb080e = crtcdata[6];
*(unsigned int *) 0xe80018 = *(unsigned int *) 0xe8001c
= *(unsigned int *) 0xe80020 = *(unsigned int *) 0xe80024
= (0 << 16) + 0; /* グラフィック画面の座標 */
*(unsigned short *) 0xe82500 = 0b01001001001110; /* 優先順位 TX>SP>GR */
/* テキスト画面のパレットを設定 */
s = (unsigned short *) 0xe82200;
for (i = 0; i < 16; i++)
*s++ = textpalet[i];
_iocs_b_super (sp);
TxfontInit (); /* フォント関連の初期化 */
_iocs_b_curoff (); /* カーソルを消す */
xsp_vsyncint_on (&VdispRoutine);
pcm8a_vsyncint_on ();
}
/* タイトル画面の表示 */
static int Title (void)
{
int cy = 0; /* カーソル位置 */
int old_t;
int t;
int i, j;
int sp;
char temp_str[32];
enum {
JOY_NON = 0, JOY_UP, JOY_DOWN
};
sp = _iocs_b_super (0);
*(unsigned short *) 0xe82600 &= 0xfff0; /* グラフィック画面表示オフ */
_iocs_b_super (sp);
TextClear ();
/* スプライトのパレットデータを定義 */
/* (1パレットブロック=16色) × (15ブロックぶん) 定義する */
{
unsigned short *p = (unsigned short *) title_pal_dat;
for (i = 1; i < 16; i++)
for (j = 0; j < 16; j++)
_iocs_spalet (0x80000000 | j, i, *p++);
}
#define IPPON_X 24 /* "IPPON-YARI" を表示する座標 */
#define IPPON_Y (8*16)
#if 0
/* "IPPON" と "YARI" が上下からやってくる */
for (i = 16; i > 0; i--) {
xsp_vsync (1);
xobj_set (IPPON_X, IPPON_Y - i * 12, obj_title + 2, 0x0130); /* IPPON(影) */
xobj_set (IPPON_X + 9 * 16, IPPON_Y + i * 12, obj_title + 3, 0x0130); /* YARI(影) */
xsp_out ();
}
#else
/* "IPPON" と "YARI" が上下からやってくる */
for (i = 12; i > 0; i--) {
xsp_vsync (1);
xobj_set (IPPON_X, IPPON_Y + i * 2, obj_title + 2, 0x0130); /* IPPON(影) */
xobj_set (IPPON_X + 9 * 16, IPPON_Y + i * 2, obj_title + 3, 0x0130); /* YARI(影) */
xsp_out ();
}
#endif
xobj_set (IPPON_X, IPPON_Y, obj_title, 0x0130); /* IPPON */
xobj_set (IPPON_X + 9 * 16, IPPON_Y, obj_title + 1, 0x0130); /* YARI */
xsp_out ();
TxfontCursor (0, 26);
TxfontPuts (
" (C)PROGRAMMED BY MITSUKY 2000\n"
" GRAPHICS BY H.SUZUKI\n\n"
" VER1.0 FOR DENNOU CLUB VOL.147\n");
#define START_X 10 /* "START" を表示する座標 */
#define START_Y 20
TxfontCursor (0, START_Y);
TxfontPuts (
" START\n"
" EXIT\n"
);
TxfontCursor (START_X, START_Y + cy);
TxfontPutchar ('>');
while ((_iocs_joyget (0) & 0b01101111) != 0b01101111); /* ジョイスティックが離されるまで待つ */
while (_iocs_bitsns (0x0c) & 0b10); /* [BREAK] が離されるまで待つ */
#define SCORE_X 2
#define SCORE_Y 0
#define HIGH_SCORE_X 21
sprintf (temp_str, "HI %06d", high_score);
TxfontCursor (HIGH_SCORE_X, SCORE_Y);
TxfontPuts (temp_str);
sprintf (temp_str, "SCORE %06d", score);
TxfontCursor (SCORE_X, SCORE_Y);
TxfontPuts (temp_str);
old_t = JOY_NON;
do {
xsp_vsync (1);
t = _iocs_joyget (0);
if (((t & 0b0001) == 0) && (cy > 0)) { /* 上 */
if (old_t != JOY_UP) {
TxfontCursor (START_X, START_Y + cy);
TxfontPutchar (' ');
cy--;
TxfontCursor (START_X, START_Y + cy);
TxfontPutchar ('>');
old_t = JOY_UP;
}
}
if (((t & 0b0010) == 0) && (cy < 1)) { /* 下 */
if (old_t != JOY_DOWN) {
TxfontCursor (START_X, START_Y + cy);
TxfontPutchar (' ');
cy++;
TxfontCursor (START_X, START_Y + cy);
TxfontPutchar ('>');
old_t = JOY_DOWN;
}
}
if ((t & 0b1111) == 0b1111) {
old_t = JOY_NON;
}
if (_iocs_bitsns (0x0c) & 0b10) { /* [BREAK] */
while (_iocs_bitsns (0x0c) & 0b10);
cy = SELECT_EXIT;
break;
}
} while ((t & 0b01000000) != 0);
while ((_iocs_joyget (0) & 0b01000000) == 0);
xsp_out ();
return (cy);
}
/* ゲーム本体 */
static void Game (void)
{
int i, j;
int sp;
int old_score = -1; /* 初回は必ず表示されるように */
int sprites; /* 表示スプライト数 */
char temp_str[32];
TextClear ();
/* グラフィック画面のパレットを設定 */
for (i = 0; i < 64; i++)
_iocs_gpalet (i + 16, bg_pal[i]);
GvramInit (); /* グラフィック画面関連の初期化 */
/* スプライトのパレットデータを定義 */
/* (1パレットブロック=16色) × (15ブロックぶん) 定義する */
{
unsigned short *p = (unsigned short *) pal_dat;
for (i = 1; i < 16; i++)
for (j = 0; j < 16; j++)
_iocs_spalet (0x80000000 | j, i, *p++);
}
sp = _iocs_b_super (0);
*(unsigned short *) 0xe82600 |= 0x000f; /* グラフィック画面表示オン */
_iocs_b_super (sp);
score = 0;
sprintf (temp_str, "HI %06d", high_score);
TxfontCursor (HIGH_SCORE_X, SCORE_Y);
TxfontPuts (temp_str);
PlayerInit ();
ShotInit ();
EnemyInit ();
EshotInit ();
EffectInit ();
EntryInit ();
PlayerAlloc ();
player->rest = 3; /* 残機設定 */
DispRest (); /* 残機数表示 */
pause_flag = 0;
do {
xsp_vsync (0); /* 垂直同期を待つ */
EntryMove ();
PlayerMove ();
ShotMove ();
EnemyMove ();
EshotMove ();
EffectMove ();
SoundMove ();
sprites = xsp_out (); /* 表示 */
if (score != old_score) { /* 更新された時のみ表示 */
old_score = score;
sprintf (temp_str, "SCORE %06d", score);
TxfontCursor (SCORE_X, SCORE_Y);
TxfontPuts (temp_str);
}
#ifdef DEBUG
sprintf (temp_str, "ESHOT %03hd", eshot_sum);
TxfontCursor (0, 2);
TxfontPuts (temp_str);
sprintf (temp_str, "ENEMY %03hd", enemy_sum);
TxfontCursor (0, 3);
TxfontPuts (temp_str);
sprintf (temp_str, "SPRITES %06d", sprites);
TxfontCursor (0, 4);
TxfontPuts (temp_str);
#endif
} while ((player->game_over == GAME_PLAY) || (player->game_over == GAME_COMPLETE));
pause_flag = !0;
switch (player->game_over) {
case GAME_OVER:
TxfontCursor (11, 14);
TxfontPuts ("GAME OVER");
SoundMusic (MUSIC_GAME_OVER);
WaitTime (55 * 10);
break;
case GAME_COMPLETE: /* ここには来ないはず */
case GAME_COMPLETE2:
xsp_out ();
while (--player->rest > 0) {
score += 10000; /* 残機1機につき 10000pts */
DispRest (); /* 残機数表示 */
sprintf (temp_str, "SCORE %06d", score);
TxfontCursor (SCORE_X, SCORE_Y);
TxfontPuts (temp_str);
if (player->rest > 1)
WaitTime (30);
}
TxfontCursor (11, 14);
TxfontPuts (" COMPLETE");
SoundMusic (MUSIC_GAME_OVER);
WaitTime (55 * 10);
break;
case GAME_ABORT:
SoundFadeOut (64);
break;
default:
break;
}
xsp_out (); /* スプライトを消去 */
if (score > high_score)
high_score = score;
}
int main (int argc, char *argv[])
{
if (argc != 1) {
usage ();
return (-1);
}
Init ();
while (Title () == SELECT_START) {
Game ();
}
Tini ();
return (0);
}